Skip to content

Hold named build contexts to the host, and accept the frontend's sandbox settings - #2183

Closed
MayCXC wants to merge 5 commits into
apple:mainfrom
MayCXC:build-context
Closed

Hold named build contexts to the host, and accept the frontend's sandbox settings#2183
MayCXC wants to merge 5 commits into
apple:mainfrom
MayCXC:build-context

Conversation

@MayCXC

@MayCXC MayCXC commented Aug 27, 2026

Copy link
Copy Markdown

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Four commits on top of #2020, which this branch carries as its first commit and which is @0Itsuki0's work rather than mine. I raised the design point on that PR rather than filing a rendition of it, and the offer there stands: I will reshape this however is least disruptive. Related: #1930 asks for the feature, #2037 is the empty-context report beside it.

The host owns the name-to-root mapping. A named build context crosses the shim boundary as the local-dir name BuildKit assigned it, and the host resolves that name against the directories the command line declared: BuildFSSync validates each declared directory at init exactly as it validates the primary context, resolves every walk, read and info transfer through the one name-to-root lookup, and refuses a name that was never declared. The CLI resolves local context values to absolute paths when it validates the flag, so neither the API server's nor the builder VM's view of a relative path can change which directory is served, and non-local references (image, git, URL, oci-layout) pass through to the builder untouched.

That shape is BuildKit's own. In v0.29.0 session/filesync/filesync.go, FSSync() sets opts[keyDirName] unconditionally and fsSyncProvider.handle() resolves that name with sp.dirs.LookupDir(dirName), answering NotFound: no access allowed to dir %q for a name that is not registered: the requester supplies a NAME and the server holds the PATHS. It matters here specifically because BuildPipelineHandler documents a containment guarantee, openat(O_NOFOLLOW) at every descent step and canonical-path containment inside the context root, and a path arriving from inside the builder VM moves that boundary into the VM. With one root that is invisible; with named contexts there are several roots and the guarantee has to hold for each.

The sandbox settings the frontend applies to every RUN. The dockerfile frontend takes a set of per-RUN settings that container build had no way to ask for: extra host entries, a sandbox hostname, the size of /dev/shm, resource limits, a cgroup parent, and the network mode. Each is validated against the shape the frontend parses, so a malformed value is refused before a builder VM starts, and --shm-size additionally accepts the suffixed sizes the other size flags take and hands the frontend the plain byte count it wants. https://github.com/moby/buildkit/blob/v0.29.0/frontend/dockerui/attr.go

A missing oci-layout directory is refused with its real cause. An oci-layout build context names a layout directory on this machine; when the directory does not exist the value used to fall through to image-reference parsing and fail with a misleading invalid-domain error.

Dependency and Merge Order

Depends on #2020 (carried as this branch's first commit) and on the shim halves: apple/container-builder-shim#88, and apple/container-builder-shim#99 for the dir-name relay this resolves against and the sandbox attrs it fills. Merge order: apple/container-builder-shim#88, then #2020, then apple/container-builder-shim#99, then this.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

Root selection from the relayed dir-name is pinned by tests: a declared name serves from its root, the reserved names and absent metadata serve from the primary context, an undeclared name is refused with unknownNamedContext, the symlink boundary enforcement is shown holding under a named root, and init refuses a named directory that does not exist.

The sandbox settings were verified by observables inside RUN rather than by the build reporting success: hostname, a getent entry for --add-host, nofile 1234, and /dev/shm at 128m.

Every named-context value form verified end to end: local dir (a five-context fixture), docker-image:// (alpine read back), oci-layout:// (an image saved and untarred as the layout), git@ and https://…git (a README read back), and local:<other>. input:<stage> is the one dockerui row that is not applicable here, since only bake has a producer to bind it to.

Integration suite: 397 passed. Unit suite: 772 passed. make fmt, make check clean.

0Itsuki0 and others added 5 commits August 27, 2026 20:16
A named build context crosses the shim boundary as the local-dir name
BuildKit assigned it, and the host resolves that name against the
directories the command line declared: BuildFSSync validates each
declared directory at init exactly as it validates the primary context,
resolves every walk, read and info transfer through the one
name-to-root lookup, and refuses a name that was never declared. The
CLI resolves local context values to absolute paths when it validates
the flag, so neither the API server's nor the builder VM's view of a
relative path can change which directory is served, and non-local
references (image, git, URL, oci-layout) pass through to the builder
untouched.
The dockerfile frontend takes a set of per-RUN sandbox settings that
container build had no way to ask for: extra host entries, a sandbox
hostname, the size of /dev/shm, resource limits, a cgroup parent, and
the network mode. Each is validated against the shape the frontend
parses, so a malformed value is refused before a builder VM starts, and
--shm-size additionally accepts the suffixed sizes the other size flags
take and hands the frontend the plain byte count it wants.
https://github.com/moby/buildkit/blob/v0.29.0/frontend/dockerui/attr.go
Root selection from the relayed dir-name: a declared name serves from
its root, the reserved names and absent metadata serve from the primary
context, an undeclared name is refused with unknownNamedContext. The
symlink boundary enforcement is shown holding under a named root, and
init refuses a named directory that does not exist.
An oci-layout build-context names a layout directory on this machine;
when the directory does not exist the value used to fall through to
image-reference parsing and fail with a misleading invalid-domain
error. Name the actual problem before a builder starts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants